/* This file is part of the Scriptic Virtual Machine
 * Copyright (C) 2009 Andre van Delft
 *
 * The Scriptic Virtual Machine is free software: 
 * you can redistribute it and/or modify it under the terms
 * of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package scriptic.vm;

import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;

import javax.swing.SwingUtilities;

import scriptic.tokens.ScripticParseTreeCodes;

/**
 * Node in the run-time tree.
 * Most features are implemented in subclasses. * <BR>
 * <H1> Outline of main functions of the Scriptic Run-Time System </H1>
 * <CODE>
Notation Matters
--------------------------------------------
'=' means: refinement
'>' with indentation means: partial task, call
'<' in Inheritance Hierarchy means: implements
Trivial refinements are omitted
Implied sequencing is vertically



Run-Time Node Tree
------------------
The main structure in the run-time system is the run-time Node tree.
Node instances are in a hierarchic tree, using links named
parent, prev, next and firstChild.
In case of established communication, the tree is actually not
a tree but a non-circular directed graph. Then Comm(unication)Nodes
are active, which have no parent (==null) but instead a 'partners'
array referencing to involved CommRequestNodes.
There are some shortcut links in the run-time node tree:

Shortcut Link       Description
---------------------------------------------
refinementAncestor  the script at top level
  operatorAncestor  operator ancestor, e.g., *&+|/ (operatorAncestor.operatorAncestor==operatorAncestor)
      reacAncestor  reactive ancestor, i.e. '-' or '%'
       subRootNode  the ancestor node just under the RootNode



Template Tree
-------------
To ease creation of the Run-Time Node Tree, static template trees
are created at startup time, by parsing the simplified script strings
that have been generated by the preprocessor or the compiler.
There is a final class NodeTemplate.



Activating Nodes
----------------
A new Node for a given template is usually created by calling
theTemplate.ActivateFrom(the parent node.
In case of some operator types (for, while, if, switch, break, {:}, .., -)
no new node is created; the activation then has a special semantics.
To cope with the semantics of the activation, the ActivateFrom function
returns a bitSet with such bits as:

  BitField  Description
-----------------------------------------------------------
   CodeBit  has any (non-tiny) code fragment been activated
SuccessBit  does this activation result in a success for the parent,
            e.g., with "-" as an operand (epsilon), or with {:}
   SomeBit  has  ".."   been activated
   ExitBit  has "break" been activated

The activator has to pas this bitset onwards, or, in case of an OperatorNode,
take appropriate action.

Activating Communication
------------------------
Communication requests are script calls that are to communicate with
others, or send or receive expressions over a channel.
Activating a communication request may make the communication 
look possible, i.e., it may be the last partner in a communication
that had not been activated. For example,

x = c<< & c>>
c<<>> = {a} + {b}

Activating x means activating c<< (nothing special happens)
and then c>>: now the communication c<<>> starts to look possible
and {a} + {b} is activated.
If x were c<< + c>> actual communication cannot occur, since
both requests are exclusive. However, we still say c<<>>
looks possible; at a later stage, when {a} and {b} are tried out,
it is investigated whether there is an actual set of requests
for this channel of which the members are not exclusive.

Excluding Nodes
---------------
When a code fragment succeeds, others may be excluded, e.g.,

{p} + {q} + c<<

When {p} succeeds, {q} is excluded, and so is c<<. The latter
is not a code fragment but a communication request. It's exclusion
may imply that communication over c<<>> starts to look impossible,
and the activated script body then gets deactivated.
On the other hand, with {p} + {q} + c<<, if communication over the
channel becomes real (for the first time a code fragment in it 
is tried out successfully), then {p} and {q} are excluded because
they are exclusive to a partner in the communication.

Succeeding Nodes
----------------
An empty process (-) has success upon activation.
A code fragment that is tried out successfully, has also success.
These successes are transferred to the parent nodes.
It depends on the parent what happens then.
E.g., if it is a sequence operator node (;), and if the success
comes from a child that is not the rightmost one in the static 
template tree, then a child is activated according to the next
template. E.g., activating -;x activates the empty process first.
This has a success which is reported through the successbit.
Then, during the same activation cycle, x is activated.
In {a};x a successful try-out of {a} also results in activating x,
but only at a later stage, in the function Node.succeed.
A success by x (the right-most operand) will be propagated upwards
by the sequence node, to its parent.
See the source code of Node.succeed() for the behavior of 
each operator.

Deactivating Nodes
------------------
Nodes may be deactivated for different reasons.
First consider leaf nodes: a code fragment having been tried out 
successfully, gets deactivated thereafter. This is a so-called 
*active* deactivation. Alternatively, a code fragment or a communication
request may also be excluded, causing an *inactive* deactivation.
Deactivation propagates to parent nodes as long as they have no more
active childs.
Active deactivations may result in activations, as with the 
% operators, or in successes, as with the negation operators.
An active deactivation of a communication script results in
active deactivation of the involved partner communication requests,
so propagation continues.
See the source code of Node.deactivate().

Frames
------
Frames are structures between templates and run-time nodes
for communication script declarations and partner script calls.

Partner frames are owner of request lists with communication request
(of the same associated script).
E.g., activating main() in
  scripts
    A,B  = ....
    main = A,A,A, ...
would initially enter 3 CommRequests (for A) into A's frame.

A partner frame with empty request list is called inactive;
otherwise it is called active.
Communication frames for which all associated partner frames are active,
are also called active; otherwise they are inactive.
An active communication frame has an associated trial tree:
a CommNode with child nodes activated from the template.
This tree is not yet bound to specific partner requests.
That changes after successfully trying out a code fragment
for the first time in this tentative tree.

When a partner frame changes from active to inactive or back,
this may have impact on the state of the associated communication frames.
At such moments trial trees may be activated or deactivated.



Unbound Code Fragments
--------------------------------------------
Tentative communication allways starts with a 'trial tree',
  which is not yet bound to communicating partners.
  initially its activated code fragments are not bound either
  Such unbound code fragments are tried out by binding them
  tentatively to sets of partners, yielding a proper parameter context
  If the code fragment is unsure, and its trying out fails,
  then the code fragment is not deactivated; it may be retried again



Request Nodes
----------------------------------------------------------------
Code fragments and activated communication partners are classified
as 'RequestNode's. These can be put into request lists, which are ordered
on priority and duration. When entering the list, the duration attribute
is translated from an absolute value to a difference value.

For communication request nodes, the list owner ...
For code fragments, the request list owners are 'SpecificOperands', see below.



Specific Operands
-----------------------------------------------------------------------
Specific Operands are parallel data structures, shadowing those nodes
that are operands of parallel operators ( || && | &  / ) and of launched nodes,
threaded nodes communication, and the 'rootScriptCall' (and maybe others).
These operands also form a hierarchic run-time tree, which reflects
shortcuts in the main run-time tree.
The specific operands maintain their own list of request
nodes, to be distinguished of the request list.

This hierarchy and the lists enables efficient checking on mutual exclusion by
tentative communication partners ( as in A>>()|A<<() ). Moreover, it enables
efficient exclusion of code fragments and communication requests when a
code fragment is successfully tried out


CAVEAT WITH STATIC INITIALIZERS
-------------------------------
Previously, the Node had its member

    static int instances;

explicitly initialized to 0:

	static int instances = 0;

THIS WAS WRONG. INITIALIZATION IS BY DEFAULT ALREADY TO 0.
Other static initializers (e.g. i RootNode, CommRootNode etc)
created 2 nodes during load time. Each creation would increment
the 'instances' count. ONLY THEN, the initializer '= 0' would
take effect. So the instances count would start over again,
giving nodes inadequate instance numbers.


Node Inheritance Hierarchy
--------------------------
    Node
        CommNode                     < TryableNode,         RefinementNodeInterface
          ChannelNode
            SendChannelNode
            ReceiveChannelNode
        ScriptNode                   < CalleeNodeInterface, RefinementNodeInterface
        ScriptCallNode               < CallerNodeInterface
<<()      SendCallNode
>>()      ReceiveCallNode
 <      ActivationNode
 >      DeactivationNode
?:      BiTernaryTestNode
        RequestNode
          CommRequestNode            < CalleeNodeInterface
<<()        SendRequestNode
>>()        ReceiveRequestNode
          CodeFragmentNode           < TryableNode
{  }        PlainCodeFragmentNode
{??}        UnsureCodeFragmentNode
{**}        ThreadedCodeFragmentNode < Runnable
          SubRootNode                < Runnable, CalleeNodeInterface(??)
            CommRootNode
            RootScriptCallNode       < CallerNodeInterface
(<>)    LaunchedNode                 < CallerNodeInterface
        RootNode
        OperatorNode
          ParallelNode
 /          ParBreakNode
            NormalParallelNode
 ,            ParAndNode
 &              ParAnd2Node
~,            ParOrNode
 +              ParOr2Node
 ;        SeqNode
~;        NotSeqNode
 |        OrNode
 %        BreakNode
 -        NotNode
 ~        NotNode2

Other kinds of operators exist (for, while, if, switch, break, {:}, .., -),
but when corresponding templates are activated, no run-time nodes
need be created.
Conceptually, most RequestNodes are not branching Nodes; they have no childs.
However, Nodes have the branching support.



Specific Operands Inheritance Hierarcy
--------------------------------------
SpecificOperand
  ParallelOperand
    ParBreakOperand
  CommunicationOperand  --- not used; to be deleted?
  RootOperand
  SubRootOperand
  RootOfOperands



Example
-------
  main    = (<L>); C<<(), C>>()
  C<<>>() = A / B

After launching L and T:
Possible Run-Time Hierarchy of Nodes and Specific Operands
----------------------------------------------------------
rootNode                              RootOfOperands
    C<<>>CommNode                         RootOperand
      /
        A ScriptCallNode                    ParBreakOperand
        B ScriptCallNode                    ParBreakOperand
    main ScriptNode                       RootOperand
      ;
        ,
          C<<SendCallNode                   ParallelOperand
            C<<SendRequestNode
          C>>ReceiveCallNode                ParallelOperand
            C>>ReceiveRequestNode
    LaunchedNode                          RootOperand
      L ScriptNode


EventHandlingCodeFragmentNodes
------------------------------
EventHandlingCodeFragmentNodes enter request lists, linked from 
anchors via a hashmap. When bound to succeed, they enter
the request list ehcfSuccesses, later to be picked up
by the SubRootNode (in a different thread).



General Pseudo-code on top-level functions
------------------------------------------

CASE 1: main script
-------------------
main
  (node = FromJava.main():new RootScriptCallNode).startScript
  >> RootNode.enterMutex
     node.frame.template.activate
     RootNode.exitMutex

(CURRENT)
     if RootNode.myThread == null     // not already running: start it...
        node.start
        >> (new node.myThread).start   
        FromJava.mainLoop       // runs RootNode
        wait until myThread is ready:
     else FromJava.mainLoop



HasActivity Pseudo Code
-----------------------
  SubRootNode.run = while (hasActivity)

  commRootNode.hasActivity =

            enterMutex
	    if no pendingCodeFragments: return false
	    determine the priority for this round
	    try the private fragments with at least the same priority;
	    > if such a priority is higher, then adjust the round's priority
	    > distinction plain vs unsure is impossible since unsure can become sure
	    if still no higher priority came up of this' pendingCodeFragments
	       determine the time to elaps
	    let time elapse: tell to FromJava, other threads, subthreads
                                   and private successes; let these succeed if OK
	    exitMutex
            return true;

  subRootNode.hasActivity = enterMutex
                            doWork   ...a bit similar, but simpler...see RootNode.java
                            exitMutex




Outline of main calls to get code fragments executed
----------------------------------------------------
CodeFragmentNode.tryOut =
  if !event available: return false
  if this is in an unbound communication
     commNode.findAndTryPartnersFor (this)
     return the result; if OK accept the event first
  else tryOutInBoundMode

PlainCodeFragmentNode.tryOutInBoundMode =
	    deschedule
	    atomicActionHappens
	    scheduleSuccess
	    exitCriticalSection
	    doCode
 	    enterCriticalSection
	    return true

UnsureCodeFragmentNode.tryOutInBoundMode =
	    doCode
	    if success:
		    deschedule
		    atomicActionHappens
		    scheduleSuccess
		    return true
	    else
		if was bound  // i.e. was not tentatively bound in communication
		    deschedule
		    markForDeactivation
		return false;

commNode.findAndTryPartnersFor(TryableNode) =
            ...
	    tryableNode.tryOutInBoundMode
            >> doCode
               >> deschedule
                  atomicActionHappens
                  scheduleSuccess
               bindToPartners
	       >> all partners.deschedule
	          frame.activateWhenAllPartnerActive

atomicActionHappens =
            parOpAncestor request list = the succeeded request
            conflicting requests.exclude


TRY-OUT CODE: EXECUTION EXAMPLE
-------------------------------
example = (some; key>>'c'!); key>>'x'!

press 'x'. Then in Key's {??}.TryOut should do in sequence:


TryOut
  findAndTryPartnersFor
  >> set partners array
     tryOutInBoundMode
     >> doCode
        >> deschedule
           atomicActionHappens
           >> parOpAncestor request list = ['c' request];
              'x' request.exclude
	   scheduleSucess
        bindToPartners
	>> all partners.deschedule
	   frame.activateWhenAllPartnerActive


HasActivity IN MAIN LOOPS
-------------------------
The administration of the RootNode runs in a main loop,
which calls the function HasActivity repeatedly.
HasActivity performs run-time tree administration and code
execution.

To enforce mutual exclusion of commRootNode.hasActivity on the
one hand, and the hasActivity by the other SubRootNodes on the
other hand, each of those SubRootNodes calls a enterMutex or
exitMutex function on entering (c.q. exiting) hasActivity.
The commRootNode calls those functions at each of the subRootNodes.
These two functions implement simple semaphore operations ("wait"
and "signal"), implemented using a counter and Object.wait(),notify().

Special care is needed when starting new SubRootNodes.
These may only enter the list of busySubRootNodes at the
CommRootNode, when the comRootNode itself is not in its critical section,
so that comRootNode will call SubRootNode.enterMutex when entering
its critical section.
Therefore this insertion into busySubRootNodes requires waiting on the
CommRootNode's private mutex.


RACE CONDITIONS ETC.
--------------------
Race conditions exist in the previous chapter, which obstruct script
execution.

C - CommRootNode (unique)
S - Other SubRootNode (may be many)

The problem is in S entering and exiting the busySubRootNodes list.
C uses this list to see on what mutexes it should wait.
While C is in such a waiting state, the list should not be altered,
hence entering&exiting C.mutex during S.init.

S may only start its main loop when it is sure that C knows about
it in its BusySubRootNodes list. Therefore S puts itself in C's
NewSubRootNodes list, and subsequently waits for clearance by C.
C checks the NewSubRootNodes, puts those in the BusySubRootNodes
lists, and notifies those with the clearance signal.

Outline of initialisations and main loops:

S.init = enter C.mutex
           addToNewSubRoodNodes
           activate tree
         exit C.mutex

S.body = enter  S.mutex
           if first pass: wait for C's clearance signal
           doWork
           removeFrom&addTo BusySubRootNodes
         exit   S.mutex;

C.init = ...

C.body = enter C.mutex
           for S in NewSubRootNodes:
                 set S.priority high
                 add S to BusySubRootNodes
                 notify S with clearance signal
           for S in BusySubRootNodes with current priority/duration:
                 enter S.mutex
             doWork
           for S in BusySubRootNodes with current priority/duration:
                 exit S.mutex
         exit C.mutex

</CODE>
 */
public abstract class Node implements ScripticParseTreeCodes,
                                      NodeInterface {

    /** master tracing switch */
    public static final boolean traceOK = /* / false; /*/ true; /**/
    /** tracing switch */
    public static       boolean doTrace = /**/ false /*/ true /**/ & traceOK;

    /** the width of the first column in tracing output */
	public static final int lengthCol0 = 80;
	/** stream to print tracing output on, if not null */
        public static PrintStream traceStream;
    /** trace this without further information */
	void trace () {trace("");}
	/** print the given string to the console and to the traceStream, if not null */
	public static void debugOutput(String s) {System.out.println(s);
                           if (traceStream!=null)traceStream.println(s);}
    /** if doTrace: trace the given string to the console and to the traceStream */  
	public static void traceOutput(String s) {if (!doTrace) return;debugOutput(s);}
    /** if doTrace: trace the given string to the console and to the traceStream */  
	public static void traceOutput(StringBuffer s) {traceOutput(s.toString());}

    /** if doTrace: trace the given string with info on the given Node
     * to the console and to the traceStream */  
	private static synchronized void trace (Node n, String s)
	{ if (!doTrace) return; traceOutput (s+" "+n.info());}

    /** if doTrace: trace the given string with info on this Node
     * to the console and to the traceStream */  
	public void trace (String s) {trace(this,s);}
	
	/** answer information on this Node: the name and toString() */
        String info() {return getName()+" "+this;}
        
    /** trace the root node and all its descendants */
    public void traceItAll() {rootNode.traceIt();}

    /** answer a hierarchical text tree of nodes names (in column 0, indented)
     *  and their toString values in column 1; starting nesting level 0
     */
        StringBuffer infoNested() {return infoNested(0);}
    /** answer a hierarchical text tree of nodes names (in column 0, indented)
     *  and their toString values in column 1; with the given starting nesting level
     */
        StringBuffer infoNested(int nestingLevel) {
            if (!traceOK) return new StringBuffer();
	    int posToken = nestingLevel*1;
	    if (posToken >= lengthCol0) posToken = lengthCol0-1;
            StringBuffer result = new StringBuffer();
            String str = getName();
   	    int i;
	    for (i=0; i<lengthCol0; i++) {
	        if      (i < posToken)     result.append(i%4==2? ' ': ' ');
	        else if (i== posToken)     result.append(str);
	        else if (i > posToken
                           + str.length()) result.append(' ');
	    }
            result.append(this).append('\n');
	    for (Node node=firstChild; node!=null; node=node.next)
	        result.append(node.infoNested (nestingLevel+1));
            return result;
	}

    /** answer the class name without the "scriptic.vm." prefix, if present */
	public String getClassName() {return getClassName(this);}
    /** answer the class name of the given object without the "scriptic.vm." prefix, if present */
	static String getClassName(Object obj) {
	       String result = obj.getClass().getName();
	       if    (result.startsWith("scriptic.vm."))
	              result = result.substring("scriptic.vm.".length());
	       return result;
	}
	/** Answer the name, from the template */
	public final String getName() {
            return template==null? "NO TEMPLATE at:"+instanceNr
                                 : template.getName(); // + "[" + instanceNr + "]";
        }
    /** answer various descriptive information in a String:
      * instance number, class name, [code index if >= 0], ".." if iteration,
      * @instance number of subSubroot node, pass if > 0, priority if != 0,
      * ssr: instance number of subSubRootNode
      * sr: instance number of subSubRootNode
      * poa: instance number of parOpAncestor
      * and some more info (see code)
      */
	public String toString() {
            if (!traceOK) return "";
            StringBuffer result = new StringBuffer();
	    result.append(instanceNr)
                  .append(": ")
                  .append(getClassName())
                  .append(template!=null?
                          template.codeIndex>=0? "["+template.codeIndex+"]"
                                               : ""
                                        : "TEMPLATE MISSING")
	          .append(isIteration? "..": "")
	          .append("@" + (subRootNode==null? "--": (""+subRootNode.instanceNr)));
            if (pass     != 0  ) result.append(" pass:" + pass);
            if (priority != 0  ) result.append(" priority:" + priority);
	    result.append(" ssr:" + (subRootNode!=null? subRootNode.instanceNr:-1))
	          .append( " sr:" + (subRootNode!=null
                                   && subRootNode!=null?  subRootNode.instanceNr:-1))
	          .append(" poa:" +(parOpAncestor ==null?     -1
			       :parOpAncestor.node==null? -2
			       :parOpAncestor.node.instanceNr));
	    if(parOpAncestor     !=null
            && parOpAncestor.node==this)
            result.append(" R:").append(parOpAncestor.requestsString());
            result.append(" act:" + activeChilds);
            if (localData!=null)
            result.append(" loc:").append(localData.length);
            return result.toString();
	}

    /** bit for code having been activated */
         static final byte   CodeBit    = 1;
    /** bit for success */
         static final byte   SuccessBit = 2;
    /** bit for exiting loop */
         static final byte   ExitBit    = 4;
    /** bit for optional exit (..) */
         static final byte   SomeBit    = 8;

	/** whether this has success; default true */
        public Boolean success = Boolean.TRUE;  /*code fragment succeeds*/
    /** priority: only for code fragments and communication requests */
        public int     priority;
    /** pass in the nearest enclosing loopable operator ( ; % & etc)
     *  0 if there is no loop 
     */
        public int     pass;

    public Object owner;

	// get/set stuff
    Object anchor;
    public final Object  getAnchor() {return anchor;}
    /** Set the anchor */
    public void setAnchor(Object anchor) {this.anchor = anchor;}
	/** answer the priority */
	public final int     getPriority ()        {return priority;}
	/** answer the pass */
	public final int     getPass     ()        {return pass;}
	/** answer the success attribute */
	public final Boolean getSuccess  ()        {return success;}
	/** set the success attribute */
	public final void setSuccess  (Boolean v)  {success = v;}
	/** set the success attribute */
	public final boolean setSuccess  (boolean v)  
	{
		success = v? Boolean.TRUE: Boolean.FALSE;
		return v;
	}
	/** set the success attribute to TRUE if v, else to null; answer whether it was TRUE*/
	public final boolean setSuccessTrueOrNull(boolean v)
	{
		success = v? Boolean.TRUE: null;
		return v;
	}
    /**
     * Cancel the iteration, if any; applicable for eventHandlingCodeFragments
     */
    public void breakIteration() {}
	/** answer the original duration */
	public       double  oldDuration ()        {return NO_DURATION;}
	/** answer the duration that is still to go */
	public       double  getDuration ()        {return NO_DURATION;}
	/** set the duration */
	public       void    setDuration (double d){}

	/** the probably unique root node (unique except for reentrant vm instances) */
	RootNode rootNode;

	/** the unique root of operands */
	static RootOfOperands rootOfOperands;

	/** initialize RootNode and CommRootNode, if not done yet */
	//static {RootNode.staticInitializer();}

	/** number of instances created */
	static int instances;

	/** instance creation index */
	int instanceNr;

	/** if true then this is an iteration; otherwise unknown */
	boolean isIteration;

	/** parent in main run-time tree */
	Node parent;

	/** previous sibling in main run-time tree */
	Node prev;

	/** next sibling in main run-time tree */
	Node next;

	/** associated template */
	NodeTemplate template;

	/** nearest ancestor that is an operand of a parallel operator */
	SpecificOperand parOpAncestor;

	/** the cycle count at the parent's operatorAncestor at the time of this' creation */
	long cycleAtCreation;

	/** the tick count at the parOpAncestor at the time of this' last success */
	long ticksAtLastSuccess = -1;

	/** ancestor in run-time tree that is a kind of script */
	RefinementNodeInterface refinementAncestor;

	/** ancestor in run-time tree that is reactive, i.e. '-' or '%' */
	Node reacAncestor;

	/** ancestor in run-time tree (or this) that is a script operator,
         *  e.g., *&+|/ etc.
         *  if not null: operatorAncestor.operatorAncestor == operatorAncestor
         */
	OperatorNode operatorAncestor;

	/** the unique initiator of this, below the rootNode */
	Node subRootNode;

    /** stamp used for determining whether requests can be partners */
	long stamp; 
	
	/** first child node; others are reachble using prev/next links */
	Node firstChild;
	
	/** number of active child nodes */
	int activeChilds;

	/** activation sequence number:
	 *  for parallel operators: incremented like loop passes
	 *  for sequence operators: incremented for each succesful child
	 */
	int cycle;

	/** the sub-root node for the current script call from Java */
	//SubRootNode subRootNode() {
	//    SubRootNode result = (SubRootNode) subSubRootNode.parent;
	//    return result instanceof ThreadNode? result.subRootNode(): result;}

	/** code index associated with this (template) */
	public final int codeIndex()
	{
		return template.codeIndex;
	}
	/** type code associated with this (template) */
	public final int typeCode()
	{
		return template.typeCode;
	}

    void doAnchorCodeIfPresent() {
    	if ((template.codeBits&TemplateCodes.AnchorFlag) != 0) 
    	{
    		doCode(template.getAnchorCodeIndex());
    	}
    }

    /** default activation: propagate to first template child */
	int activate() {
if (template==null) {debugOutput("template NULL"); return 0;}
if(doTrace)template.trace();
	    int result = ((NodeTemplate)template.childs[0]).activateFrom(this);
	    if ((result & SuccessBit) != 0) setRecentSuccess();
	    return result;
        }

	/**
	 * Return the parameters supplied by a communicating partner <BR>
	 * Note: the refinementAncestor must be a CommNode.
	 * If the CommNode is not yet bound, then the first of the waiting
	 * requests is taken (one of those that had this' commNode activated)
	 * @parm i: index for partner.
         */
	public final ValueHolder[] paramData(int i)
	{
	    return ((CommNode)refinementAncestor).paramDataPrim(i);
	}

	/**
	 * Return the parameters of a plain ScriptNode
         */
	public final ValueHolder[] paramData()
	{
	    return ((CalleeNodeInterface)refinementAncestor).paramDataPrim();
	}

	/**
	 * Return the index values of a plain ScriptNode
         */
	public final ValueHolder[] indexValues()
	{
		int indexCount = ((Node)refinementAncestor).template.nrIndexes;
		if (indexCount==0) {
			return null;
		}
		return Arrays.copyOf(paramData(), indexCount);
	}

	/**
	 * Return the old parameters supplied by a communicating partner
	 * @parm i: index for partner.
	 * Note: the refinementAncestor must be a CommNode.
	 * If the CommNode is not yet bound, then the first of the waiting
	 * requests is taken (one of those that had this' commNode activated)
         */
	public final Object[] oldParamData(int i)
	{
	    return ((CommNode)refinementAncestor).oldParamDataPrim(i);
	}

	/**
	 * Return the old parameters of a plain ScriptNode
         */
	public final Object[] oldParamData()
	{
	    return ((CalleeNodeInterface)refinementAncestor).oldParamDataPrim();
	}

    /** local data present at this */
	public ValueHolder localData[];

	/**
	 * Set local data at a given level to a given instance
	 * @param i the level (in "int j: int k: x" 0 and 1)
	 * @param d the value
         */
	public void setLocalData(int i, ValueHolder d) {
	    ValueHolder oldArray[] = localData;
	    localData = new ValueHolder[i+1];
	    if (oldArray != null && i>0)
		System.arraycopy(oldArray,0,localData,0,i);
	    localData[i] = d;
if(doTrace) trace("setLocalData: "
		  + (( oldArray==null)?  "oldArray==null, ": "oldArray.length="+oldArray.length)
		  + ((localData==null)? "localData==null, ": "localData.length="+localData.length)
                  + "d="+d);
	}

	/**
	 * Given that this is a ScriptCallNode, return the callee's paraneters
     */
	final public ValueHolder[] calleeParams()
	{
	    return ((CalleeNodeInterface)firstChild).paramDataPrim();
	}

    /** perform the associated piece of code, if present */
	final void doCode()          {
	     if ((template.codeBits&NodeTemplate.CodeFlag) != 0) doCode (codeIndex());}
    /** perform the associated piece of code, if present, at the specified index
     *  @param index the index in the switch construct in the code function */
	final void doCode(final int index) {
		   FromJava.codeIsExecuted();
           if(index>=0){success=Boolean.TRUE;
                         if (FromJava.doCallbackExecuteCode()) {
                             FromJava.debugger.callbackExecuteCode (this);
                         }
                         if (anchor!=null 
                         && !(this instanceof EventHandlingCodeFragmentNode)
                         && !(this instanceof ThreadedCodeFragmentNode))
                         {
                        	 try
                        	 {
                        		 if ((template.codeBits & TemplateCodes.AsyncFlag)!=0)
                        		 {
	                        		 CodeInvokerAsynchronous c = (CodeInvokerAsynchronous) anchor;
	                        		 c.invokeAsynchronously(new Runnable() {
	                        			 public void run(){
	                        				 try {
												template.codeMethod.invoke(owner, Node.this, index);
											    FromJava.asyncCodeExecutionHasEnded();
								                synchronized(rootNode) {
								                	PlainCodeFragmentNode pcfn = (PlainCodeFragmentNode) Node.this;
								                	pcfn.deschedule();
								                	pcfn.scheduleSuccess();
									            }
									            FromJava.shouldWaitForUserInput = false;
									            FromJava.doNotify(); // in case it had been waitingForUserInput...

	                        				 } catch (IllegalArgumentException e) { // better exception handling needed
												throw new RuntimeException(e);
											} catch (IllegalAccessException e) {
												throw new RuntimeException(e);
											} catch (InvocationTargetException e) {
												throw new RuntimeException(e.getTargetException());
											}
	                        		     }
	                        		 });
                        		 }
                        		 else
                        		 {
                        			 CodeInvokerSynchronous c = (CodeInvokerSynchronous) anchor;
	                        		 c.invokeSynchronously(new Runnable() {
	                        			 public void run(){
	                        				 try {
												template.codeMethod.invoke(owner, Node.this, index);
											} catch (IllegalArgumentException e) { // better exception handling needed
												throw new RuntimeException(e);
											} catch (IllegalAccessException e) {
												throw new RuntimeException(e);
											} catch (InvocationTargetException e) {
												throw new RuntimeException(e.getTargetException());
											}
	                        		     }
	                        		 });
                        		 }
                        	 }
                        	 catch (Exception e) {
                        		 throw new RuntimeException(e); // better handling needed
                        	 }
                         }
                         else
                         {
            				 try {
								template.codeMethod.invoke(owner, this, index);
							} catch (IllegalArgumentException e) { // better exception handling needed
								throw new RuntimeException(e);
							} catch (IllegalAccessException e) {
								throw new RuntimeException(e);
							} catch (InvocationTargetException e) {
								throw new RuntimeException(e.getTargetException());
							}
                         }
           }
        }

    /** make a new Node; increment instanceNr */
	Node () {instanceNr = instances++;}
	/**
	 * constructor: set instance number to next value; set template, set parent
	 * @parm theTemplate template for the node
	 * @parm theParent parent for the node; not null.
	 */
	Node (NodeTemplate template, Node parent) {
	    this();
	    this.parent      = parent;
	    this.template    = template;
	    this.isIteration = template.isIteration();
	    if (parent != null)
	    {
		owner                 = parent.owner;
		rootNode              = parent.rootNode;
		localData             = parent.localData;
	        subRootNode        = parent.subRootNode; //before addChild!
                refinementAncestor    = parent.refinementAncestor4Child();
	              reacAncestor    = parent.      reacAncestor4Child();
	             parOpAncestor    = parent.     parOpAncestor;  //overridden in NormalParallelNode.addChild etc
	          operatorAncestor    = parent.  operatorAncestor;
	        parent.addChild (this); // may override subSubRootNode etc

                if (!(parent instanceof RootNode)) {
                    // SubRootNode messes around with its own attributes
	            priority = parent.priority;
	            pass     = parent.pass4Child();
                }
	    }
            if (FromJava.doCallbackActivate()) {
                     FromJava.debugger.callbackActivate (this);
            }
	}

	/**
	 * constructor: set instance number to next value; set template
	 * @parm theTemplate template for the node
	 */
	Node (NodeTemplate template) {this (template, (Node) null);}

	/** The type name in long format, e.g., "parallel-and" */
	final String longName() {return "";} // template.longName();}

    /**
     * This Node succeeds. Handle, e.g. by propagating upwards.
     * @return often 0; presumably to be ignored 
     */
	final int succeed() {
	    Node n, p;

	    for (n=this; (p=n.parent) != null; n=p) {
if(doTrace)n.trace("S>");
            if (FromJava.doCallbackSucceed()) {
                FromJava.debugger.callbackSucceed (n);
            }
			if (n.hadRecentSuccess()) return 0;
			n.setRecentSuccess();
			switch (p.template.typeCode) {
			case         NotOperatorCode:
			case ReactiveNotOperatorCode: return 0;
			case SuspendOperatorCode:
				{
					SpecificOperand s = n.parOpAncestor;
					if (s.hasSuspended) {
						s.hasSuspended = false;
						s.suspendOrResumeLeftSiblings(false);
					}
				}
	    		break;
			case    ParAndOperatorCode:
			case ParAnd2OperatorCode: {ParAndNode q = (ParAndNode) p;
					 if (++q.recentlySuccessfulChilds < q.startedChilds) return 0;
					}break;
			case ParOrOperatorCode: ((ParOrNode)p).recentlySuccessfulChilds++;
	                              break;
			case ParOr2OperatorCode: ((ParOr2Node)p).recentlySuccessfulChilds++;
				                  break;
			case ScriptDeclarationCode:
	if(false)n.trace("Script.succeeds? ");
					if (((ScriptNode)p).testParams()==Boolean.FALSE) return 0;
	if(false)n.trace("Script.succeeds! ");
				        break;
	
			case ConditionalScriptExpressionCode: if (n.template.indexAsChild==0) {
		                                   int result = p.template.childs[1].activateFrom(p);
	//trace("?: : p.template.childs[1].activateFrom(this)="+result
	//      +((result & SuccessBit) != 0? "success!": "failure"));
	                                           if((result & SuccessBit) == 0) {
	                                                return 0;
	                                           }
			                       }
			                       break;
	
			case SeqOperatorCode: //do not continue the loop here.
	                                       //!p.childSucceeds(n) may call p.succeed, if applicable
			case  CommunicationDeclarationCode:
			case        ChannelDeclarationCode:
			case    SendChannelDeclarationCode:
			case ReceiveChannelDeclarationCode: return p.childSucceeds(n);
			case      ScriptCallExpressionCode:
			case            ChannelReceiveCode:        p.childSucceeds(n); break;
			}
	    }
	    return 0;
	}

    
   /**
     * This Node is deactivated from the run-time tree. 
     * Handle, e.g. by propagating upwards.
     * @return often 0; presumably to be ignored 
     */
	final void deactivate (boolean isActively) {
	    Node n, m, p;
	    for (n=this; (p=n.parent)!=null; n=p) {
if(doTrace)n.trace("D>");
            if (FromJava.doCallbackDeactivate()) {
                FromJava.debugger.callbackDeactivate (n);
            }
			switch (p.template.typeCode) {
			case SuspendOperatorCode: 
				{
					SpecificOperand s = n.parOpAncestor;
					if (s.hasSuspended) {
						s.hasSuspended = false;
						s.suspendOrResumeLeftSiblings(false);
					}
				}
				// NO break
			case      ParAndOperatorCode:
			case  ParOrOperatorCode: n.parOpAncestor.remove(); break;
			case ParBreakOperatorCode:
			case    ParOr2OperatorCode: n.parOpAncestor.remove();
					   if (isActively && n.hadRecentSuccess())
					       for (m=p.firstChild; m!=null; m=m.next)
						   if(m!=n) m.parOpAncestor.excludeRequests();
					   break;
			case  ParAnd2OperatorCode: n.parOpAncestor.remove();
					  if (isActively && !n.hadRecentSuccess())
					       for (m=p.firstChild; m!=null; m=m.next)
						   if(m!=n) m.parOpAncestor.excludeRequests();
					   break;
	
			case ConditionalScriptExpressionCode: if (isActively
				               &&  n.template.indexAsChild==0
				               && !n.hadRecentSuccess()
				               &&  p.template.childs.length > 2) {
					           p.template.childs[2].activateFrom(p);
						   return;
					       }
			                       break;
	
			case DeactivationCodeCode: p.success = isActively && n.hadRecentSuccess();
					      p.doCode(p.codeIndex()); //do not override success
					      break;
			case RootCode: 
			case       LaunchedExpressionCode:
	                                      n.parOpAncestor.remove();
					      break;
	
			case         NotOperatorCode:
			case ReactiveNotOperatorCode:
			case      NotSeqOperatorCode:
			case  CommunicationDeclarationCode:
			case        ChannelDeclarationCode:
			case    SendChannelDeclarationCode:
			case ReceiveChannelDeclarationCode: p.childDeactivates(n, isActively); break;
			}
			n.parent        = null;
			n.parOpAncestor = null;
	
			if (n.next!=null)    n.next.prev       = n.prev;
			else                 p.firstChild.prev = n.prev;
			if (n!=p.firstChild) n.prev.next       = n.next;
			else                 p.firstChild      = n.next;
	
			p.activeChilds--;
			if (p.activeChilds>0) return;
	    }
	}

	/**
	 * perform a specific action when child n is about to deactivate.
	 * To be implemented by some specific subclasses.
	 */
	void childDeactivates(Node n, boolean isActively) {
		n.trace("ERROR: unexpected childDeactivates in " + this+": ");}

	/**
	 * one of the childs reports a success. Handle it.
	 * To be implemented by some specific subclasses.
	 */
	int childSucceeds (Node child) {
            child.trace("ERROR: unexpected childSucceeds in " + this+": ");
            return 0;
	}

	/**
	 * one of the childs had succeeded. Handle it.
	 * To be implemented by some specific subclasses.
	 */
	void childHadSucceeded (Node child) {
             child.trace("ERROR: unexpected childHadSucceeded in " + this+": ");
        }

    /** whether this hangs under | / % -; + * */
    final boolean isWithOrLikeOptr() {
	    if (operatorAncestor==null) return false;
	    return operatorAncestor.isOrLikeOptr();
	}
    /** whether this hangs under -; ; */
    final boolean isInSequence() {
	    if (operatorAncestor==null) return false;
	    return operatorAncestor.isSequence();
	}

	/**
	 * Answer whether the i'th parameter is forced
	 */
	public boolean isForced (int i)
	{
	    return refinementAncestor.isForced(i);
	}

	/**
	 * Answer whether the i'th parameter is out
	 */
	public boolean isOut (int i)
	{
	    return refinementAncestor.isOut(i);
	}

	/**
	 * Set the owner. Only relevant for EventHandlingCodeFragmentNodes
	 */
	public void setOwner (Object owner) {}

	/** answer whether this has had a recent success */
	final boolean hadRecentSuccess() {
	    return ticksAtLastSuccess==getTicks();
	}

	/** this has now a recent success */
	final void setRecentSuccess() {
	    ticksAtLastSuccess=getTicks();
	}

    /** answer the number of ticks from the ancestor node that is an
     * operand of a parallel operator node.
     * The tick count is the number of iterations in the main loop 
     * during which one or more code fragments in the subtree were
     * tried out successfully (with 'subtree' also continuing through
     * communications)
     */
	final long getTicks() {
	    return parOpAncestor.ticks;
	}

	/**
	 * Called from another script, with a given owner, template and with given data;
	 * Only valid in ScriptCallNode, LaunchedNode, LaunchedThreadNode
	 */
	public void startScript (Object owner, NodeTemplate template, Object params[]) {
            debugOutput("Illegal call Node.startScript: ");
	}


	/** mark this for deactivation, so that it will be disposed shortly */
	void markForDeactivation() {rootNode.markForDeactivation(this);}

	/**
	 * add a child node:
         * set the parent variable; adjust the active count.
	 * insert the child into the semi-closed double linked list of siblings
	 * ensure next==null
	 */
	void addChild (Node theChild)
	{
if (false)if(doTrace) trace ("ADDING CHILD: ");
	    activeChilds++;
	    theChild.cycleAtCreation = cycle;

	    if (firstChild != null)
	         firstChild.prev     = (theChild.prev = firstChild.prev).next = theChild;
	    else firstChild          = theChild.prev = theChild;
	}

	/**
	 * answer a child's nearest ancestor that is a kind of script;
	 * mostly the same as this' refinementAncestor; sometimes this, however
	 */
	RefinementNodeInterface refinementAncestor4Child() { return refinementAncestor; }

	/**
	 * answer a child's nearest ancestor that is reactive stuff, i.e. '-' or '%'
	 * mostly the same as this' reacAncestor; sometimes this, however
	 */
	Node reacAncestor4Child() { return reacAncestor; }

	/**
	 * answer a child's pass: mostly the same as this' pass;
	 * if this is a scripting operator (;&+/| etc) then different
	 */
	int pass4Child() { return pass; }


        ///////////////// NodeInterface stuff...

	/** the unique root node */
	public NodeInterface rootNode() {return rootNode;}
	public NodeInterface subRootNode() {return subRootNode;}

	/** the unique root of operands */
	// static SpecificOperandInterface rootOfOperands() {return rootOfOperands;}

	/** number of instances created */
	public int instances() {return instances;}

	/** instance creation index */
	public int instanceNr() {return instanceNr;}

	/** if true then this is an iteration; otherwise unknown */
	public boolean isIteration() {return isIteration;}

	/** parent in main run-time tree */
	public NodeInterface parent() {return parent;}

	/** previous sibling in main run-time tree */
	public NodeInterface prev() {return prev;}

	/** next sibling in main run-time tree */
	public NodeInterface next() {return next;}

	/** first child */
	public NodeInterface firstChild() {return firstChild;}

	/** active childs count */
	public int activeChilds() {return activeChilds;}

	/** associated template */
	public NodeTemplateInterface template() {return template;}

	/** associated frame */
	// ScriptFrame frame() {return frame;}

	/** nearest ancestor that is an operand of a parallel operator */
	// SpecificOperandInterface parOpAncestor() {return parOpAncestor;}

	/** the cycle count at the parent's operatorAncestor at the time of this' creation */
	public long cycleAtCreation() {return cycleAtCreation;}

	/** the tick count at the parOpAncestor at the time of this' last success */
	public long ticksAtLastSuccess() {return ticksAtLastSuccess;}

	/** ancestor in run-time tree that is a kind of script */
	public NodeInterface refinementAncestor() {return refinementAncestor;}

	/** ancestor in run-time tree that is reactive, i.e. '-' or '%' */
	public NodeInterface reacAncestor() {return reacAncestor;}

	/** ancestor in run-time tree (or this) that is a script operator,
         *  e.g., *&+|/ etc.
         *  if not null: operatorAncestor.operatorAncestor == operatorAncestor
         */
	public NodeInterface operatorAncestor() {return operatorAncestor;}

	/** activation sequence number:
	 *  for parallel operators: incremented like loop passes
	 *  for sequence operators: incremented for each succesful child
	 */
	public int cycle() {return cycle;}

	/** the sub-root node for the current script call from Java */
	//public NodeInterface getSubRootNode() {return subRootNode();}
}

